package com.hellohu.mbg.plugin;

import org.apache.commons.lang3.StringUtils;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.config.JavaClientGeneratorConfiguration;

import java.io.File;
import java.util.List;
import java.util.Properties;

/**
 * 生成baseMapper的相关代码插件
 */
public class GenerateExtendBaseMapperPlugin extends PluginAdapter {

    // mapper的基类
    private String baseMapper;
    private boolean generateExample;

    @Override
    public void setProperties(Properties properties) {
        super.setProperties(properties);
        this.baseMapper = this.properties.getProperty("baseMapper");
        this.generateExample = PluginUtil.getBooleanProperty(this.properties, "generateExample", true);
        if (StringUtils.isBlank(baseMapper)) {
            throw new RuntimeException("配置错误，未配置baseMapper");
        }
    }

    /**
     * 生成的Mapper接口
     *
     * @param interfaze         mbg的接口定义
     * @param introspectedTable mbg的table定义
     * @return 是否生成mapper接口
     */
    @Override
    public boolean clientGenerated(Interface interfaze, IntrospectedTable introspectedTable) {
        // 注释
        List<String> comment = PluginUtil.getComment(introspectedTable, (tableName, remark) -> tableName + "的Mapper");
        comment.forEach(interfaze::addJavaDocLine);
        // 获取实体类
        FullyQualifiedJavaType entityType = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());
        // 获取主键
        List<IntrospectedColumn> primaryKeyColumns = introspectedTable.getPrimaryKeyColumns();
        IntrospectedColumn singlePk = null;
        if (primaryKeyColumns != null && primaryKeyColumns.size() == 1) {
            singlePk = primaryKeyColumns.get(0);
        }
        if (singlePk == null) {
            throw new RuntimeException("没有主键，或者符合主键，目前无法支持");
        }
        // import
        interfaze.addImportedType(entityType);
        interfaze.addImportedType(new FullyQualifiedJavaType(baseMapper));
        interfaze.addImportedType(singlePk.getFullyQualifiedJavaType());
        // extend
        String generics = StringUtils.joinWith(" , ", entityType.getShortName(),
                singlePk.getFullyQualifiedJavaType().getShortName());
        // 启用example
        if (generateExample) {
            FullyQualifiedJavaType exampleType = new FullyQualifiedJavaType(
                    entityType.getFullyQualifiedName() + "Example");
            interfaze.addImportedType(exampleType);
            generics = generics + " , " + exampleType.getShortName();
        }
        interfaze.addSuperInterface(new FullyQualifiedJavaType(baseMapper + "<" + generics + ">"));
        // 判断是否已经存在，已经存在不再覆盖
        JavaClientGeneratorConfiguration config = this.context.getJavaClientGeneratorConfiguration();
        String filePath = config.getTargetProject() + File.separator
                + interfaze.getType().getFullyQualifiedName().replace(".", File.separator)
                + ".java";
        File javaFile = new File(filePath);
        return !javaFile.exists();
    }

    // 相关mapper的java代码都不生成
    @Override
    public boolean clientCountByExampleMethodGenerated(Method method, Interface interfaze,
                                                       IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientDeleteByExampleMethodGenerated(Method method, Interface interfaze,
                                                        IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientDeleteByPrimaryKeyMethodGenerated(Method method, Interface interfaze,
                                                           IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientInsertSelectiveMethodGenerated(Method method, Interface interfaze,
                                                        IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientSelectByPrimaryKeyMethodGenerated(Method method, Interface interfaze,
                                                           IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientUpdateByExampleSelectiveMethodGenerated(Method method, Interface interfaze,
                                                                 IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientUpdateByPrimaryKeySelectiveMethodGenerated(Method method, Interface interfaze,
                                                                    IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientInsertMethodGenerated(Method method, Interface interfaze,
                                               IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientSelectByExampleWithoutBLOBsMethodGenerated(Method method, Interface interfaze,
                                                                    IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientUpdateByExampleWithoutBLOBsMethodGenerated(Method method, Interface interfaze,
                                                                    IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientUpdateByPrimaryKeyWithoutBLOBsMethodGenerated(Method method, Interface interfaze,
                                                                       IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean validate(List<String> list) {
        return true;
    }
}
